<template>
  <h2>计算属性和监视</h2>
  <fieldset>
    <legend>姓名操作</legend>
    姓氏：<input
      type="text"
      placeholder="请输入姓氏"
      v-model="user.lastName"
    /><br />
    名字：<input
      type="text"
      placeholder="请输入名字"
      v-model="user.firstName"
    /><br />
  </fieldset>
  <fieldset>
    <legend>计算属性和监视的演示</legend>
    姓名：<input type="text" placeholder="显示姓名" v-model="fullName1" /><br />
    姓名：<input type="text" placeholder="显示姓名" v-model="fullName2" /><br />
    姓名：<input type="text" placeholder="显示姓名" v-model="fullName3" /><br />
  </fieldset>
</template>
<script lang="ts">
import {
  computed,
  defineComponent,
  reactive,
  ref,
  watch,
  watchEffect,
} from "vue";
export default defineComponent({
  name: "App",
  setup() {
    const user = reactive({
      lastName: "东方",
      firstName: "不败",
    });
    // 通过计算属性方式，实现姓名的显示
    // vue3 中的计算属性
    // 计算属性的函数中如果之传入一个回调函数，表示的是get

    // 第一个姓名：
    // 返回的是一个ref对象
    const fullName1 = computed(() => {
      return user.lastName + "_" + user.firstName;
    });

    // 第二个姓名：
    const fullName2 = computed({
      get() {
        return user.lastName + "_" + user.firstName;
      },
      set(val: string) {
        const names = val.split("_");
        user.lastName = names[0];
        user.firstName = names[1];
      },
    });

    // 第三个姓名：
    // 监视---监视指定的数据
    const fullName3 = ref("");
    watch(user, ({firstName, lastName}) => {
      fullName3.value = lastName + '_' + firstName
    }, {immediate: true, deep: true})
    // immediate 默认会执行一次watch，deep 深度监视

    // 不需要配置immediate，本身默认就会进行监视，（默认执行一次）
    // watchEffect(() => {
    //   fullName3.value = user.lastName + '_' + user.firstName
    // })

    // 监视fullName3的数据，改变firstName 和lastName
    watchEffect(() => {
      const names = fullName3.value.split("_");
      user.lastName = names[0];
      user.firstName = names[1];
    });

    // watch --- 可以监视多个数据的
    watch([user.firstName, user.lastName, fullName3], () => {
      // 下面代码，user.firstName, user.lastName不执行，加上了fullName3执行
      console.log('====')
      // fullName3是ref响应式的数据，但是user.firstName和user.lastName不是ref响应式的数据

    })

    /* 
    watch多个数据: 
      使用数组来指定
      如果是ref对象, 直接指定
      如果是reactive对象中的属性,  必须通过函数来指定
    */
    watch([()=>user.firstName, ()=>user.lastName, fullName3], () => {
      console.log('====2')
    })
    return {
      user,
      fullName1,
      fullName2,
      fullName3,
    };
  },
});
</script>